package com.baitiaojun.video.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baitiaojun.api.domain.video.VideoView;
import com.baitiaojun.api.exception.ConditionException;
import com.baitiaojun.api.util.ConstantUtil;
import com.baitiaojun.api.util.IpUtil;
import com.baitiaojun.api.util.SnowFlakeUtil;
import com.baitiaojun.video.mapper.VideoViewMapper;
import com.baitiaojun.video.service.VideoViewService;
import com.baitiaojun.video.support.RedisSupport;
import eu.bitwalker.useragentutils.UserAgent;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @类名 VideoViewServiceImpl
 * @描述 TODO
 * @作者 白条君
 * @创建日期 2023/2/23 16:44
 * @版本 1.0
 */
@Service
public class VideoViewServiceImpl implements VideoViewService {

    @Resource
    private VideoViewMapper videoViewMapper;

    @Autowired
    private RedisSupport redisSupport;

    @Override
    public Integer getVideoViewCount(Long videoId) {
        Object viewCount = redisSupport.getValue(ConstantUtil.VIEW_COUNT + videoId);
        if (ObjectUtils.isEmpty(viewCount)) {
            synchronized (this) {
                viewCount = redisSupport.getValue(ConstantUtil.VIEW_COUNT + videoId);
                if (ObjectUtils.isEmpty(viewCount)) {
                    Integer count = videoViewMapper.videoViewCount(videoId);
                    redisSupport.setValue(ConstantUtil.VIEW_COUNT + videoId, count, 1, TimeUnit.DAYS);
                    return count;
                }
            }
        }
        return JSONObject.parseObject(JSONObject.toJSONString(viewCount), Integer.class);
    }

    @Transactional
    @Override
    public void addVideoViewCount(VideoView videoView, HttpServletRequest request) throws ConditionException {
        Long videoId = videoView.getVideoId();
        if (ObjectUtils.isEmpty(videoId)) {
            throw new ConditionException("参数异常");
        }
        //Map构建查询参数
        Map<String, Object> params = new HashMap<>();
        //添加参数
        if (ObjectUtils.isNotEmpty(videoView.getUserid())) {
            Long userId = videoView.getUserid();
            //当userid不为null和不为空字符的时候，用于区分用户
            params.put("userid", userId);
        } else {
            //生成clientid
            String userAgent = request.getHeader("User-Agent");
            UserAgent agent = UserAgent.parseUserAgentString(userAgent);
            int clientId = agent.getId();
            //获取ip
            String ip = IpUtil.getIP(request);
            //当userid为null，clientid不为null以及当ip不为null，用于区分游客
            params.put("clientid", clientId);
            params.put("ip", ip);
            videoView.setClientid(String.valueOf(clientId));
            videoView.setIp(ip);
        }
        params.put("today", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        params.put("videoId", videoId);
        //判断是否存在此条videoview记录
        Integer existsVideoView = videoViewMapper.isExistsVideoView(params);
        //如果videoview为null就进行videoView添加
        if (ObjectUtils.isEmpty(existsVideoView)) {
            videoView.setId(SnowFlakeUtil.getNextId());
            videoView.setCreatetime(new Date());
            videoViewMapper.insertSelective(videoView);
            //将观看次数添加到redis
            Integer count = videoViewMapper.videoViewCount(videoId);
            redisSupport.setValue(ConstantUtil.VIEW_COUNT + videoId, count, 1, TimeUnit.DAYS);
        }
    }
}
